package cn.gx.kevin.common.utils;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.dom4j.io.SAXReader;

/***
 *@description :
 *@author : kevin.huang
 *@date : 2018/5/13 13:53
 @modified by
 ***/
public class XMLJSONUtils {

    public static String readXmlString(String path) throws Exception {
        SAXReader sr = new SAXReader();
        Document doc = sr.read(path);
        String str = doc.asXML();
        return str;

    }

    /**** 读取注释*******/
    static void getComments(Element element,HashMap<String, String> commentMap){
        String commentString = "";
        for (int i = 0, size = element.nodeCount(); i < size; i++) {
            Node node = element.node(i);
            boolean isElement = node instanceof Element;
            if (isElement) {
                System.out.println("This is a Element! = "+node.getName());
                if(StringUtils.isNotEmpty(commentString)) {
                    commentMap.put(node.getName(), commentString);
                    commentString = "";
                }
            } else if(node instanceof org.dom4j.Comment){
                System.out.println("This is a Comment! = "+node.getText());
                commentString = node.getText();
            }
            if(isElement) {
                Element element2 = (Element)node;
                if(element2.nodeCount() > 0) {
                    getComments(element2,commentMap);
                }
            }
        }
    }

    /**
     * xml转json
     * @param xmlStr
     * @return
     * @throws DocumentException
     */
    public static String xml2Json(String xmlPath) throws Exception{
        String xmlStr = readXmlString(xmlPath);
        return xml2Json(xmlPath,xmlStr);
    }

    public static String xml2Json(String xmlPath,String xmlStr) throws Exception{
        Document doc= DocumentHelper.parseText(xmlStr);
        Element rootElement = doc.getRootElement();
        String rootName = rootElement.getName();
        HashMap<String, String> commentMap = new HashMap<String, String>();
        getComments(rootElement,commentMap);

        LinkedHashMap<String,Object> rootJson = new LinkedHashMap<String,Object>();
        dom4j2Json(rootElement, rootJson,commentMap);

        String rootJonString = JSONObject.toJSONString(rootJson);
        return "{\""+rootName+"\":"+rootJonString+"}";
    }


    /**
     * xml转json
     * @param element
     * @param json
     */
    public static void dom4j2Json(Element element, LinkedHashMap<String,Object> json, HashMap<String, String> commentMap ){

        List<Element> chdEl = element.elements();
        if(chdEl.isEmpty()){//如果没有子元素,只有一个值
            if(isEmpty(element.getText())) {
                json.put(element.getName(), "");
            }else {
                json.put(element.getName(), element.getText());
            }
        }
        for(Element e:chdEl){//有子元素
            String elNameString = e.getName();
            if(!e.elements().isEmpty()){//子元素也有子元素
                LinkedHashMap<String,Object> chdjson=new LinkedHashMap<>();
                dom4j2Json(e,chdjson,commentMap);
                Object o = json.get(elNameString);
                if(o!=null){
                    if(o instanceof JSONArray) {
                        JSONArray array = (JSONArray)o;
                        array.add(chdjson);
                    }else {
                        JSONArray array = new JSONArray();//利用数组进行保存
                        array.add(o);
                        array.add(chdjson);
                        json.put(elNameString, array);
                    }
                }else{
                    if(!chdjson.isEmpty()){
                        json.put(elNameString, chdjson);
                    }
                }
            }else{//子元素没有子元素
                String filedName = e.getName();
                String nodeDescString = null;
                for(Object o:e.attributes()){
                    Attribute attr=(Attribute)o;
                    if(attr.getName().equals("desc")) {//提取节点上的注释
                        nodeDescString = attr.getValue();
                    }
                }
                if(commentMap.containsKey(filedName)) {
                    filedName = filedName + "-$="+commentMap.get(filedName);
                }else {
                    if(nodeDescString != null) {
                        filedName = filedName + "-$="+nodeDescString;
                    }
                }
                if(e.getText().isEmpty()){
                    json.put(filedName, "");
                }else {
                    json.put(filedName, e.getText());
                }
            }
        }
    }

    public static boolean isEmpty(String str) {

        if (str == null || str.trim().isEmpty() || "null".equals(str)) {
            return true;
        }
        return false;
    }
}
